using Prism.Mvvm;
using System.Windows;
using Prism.Commands;
using Tryit.Views;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.Json;
using Tryit.Models;
using Microsoft.Win32;
using System.Data;
using OfficeOpenXml;
using System.Collections.Generic;
using System.Diagnostics;
using Tryit.Services;
using System.Collections.Generic;

namespace Tryit.ViewModels
{
    public class CompositionAdjustmentViewModel : BindableBase
    {
        private readonly TemplateService _templateService;
        private readonly MaterialService _materialService;
        private ObservableCollection<ElementComposition> _elementList;
        private ObservableCollection<string> _templateNames;
        private string _selectedTemplateName;

        public ObservableCollection<ElementComposition> ElementList
        {
            get => _elementList;
            set => SetProperty(ref _elementList, value);
        }

        public ObservableCollection<string> TemplateNames
        {
            get => _templateNames;
            set => SetProperty(ref _templateNames, value);
        }

        public string SelectedTemplateName
        {
            get => _selectedTemplateName;
            set => SetProperty(ref _selectedTemplateName, value);
        }

        private DelegateCommand _refreshTemplatesCommand;
        public DelegateCommand RefreshTemplatesCommand => _refreshTemplatesCommand ??= new DelegateCommand(ExecuteRefreshTemplates);

        private DelegateCommand _openTemplateCommand;
        public DelegateCommand OpenTemplateCommand => _openTemplateCommand ??= new DelegateCommand(ExecuteOpenTemplate);

        private DelegateCommand _importExcelCommand;
        public DelegateCommand ImportExcelCommand => _importExcelCommand ??= new DelegateCommand(ExecuteImportExcel);

        private DelegateCommand _openMaterialCommand;
        public DelegateCommand OpenMaterialCommand => _openMaterialCommand ??= new DelegateCommand(ExecuteOpenMaterial);

        private DelegateCommand _autoAdjustCommand;
        public DelegateCommand AutoAdjustCommand => _autoAdjustCommand ??= new DelegateCommand(ExecuteAutoAdjust);

        public CompositionAdjustmentViewModel()
        {
            _templateService = new TemplateService();
            _materialService = new MaterialService();
            ElementList = new ObservableCollection<ElementComposition>();
            TemplateNames = new ObservableCollection<string>();
            LoadTemplateNames();
            SelectFirstTemplate();
        }

        private void LoadTemplateNames()
        {
            try
            {
                var templateNames = _templateService.GetAllTemplateNames();
                TemplateNames.Clear();
                foreach (var name in templateNames)
                {
                    TemplateNames.Add(name);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载模板列表失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        public void LoadTemplateData()
        {
            if (string.IsNullOrEmpty(SelectedTemplateName))
                return;

            try
            {
                var template = _templateService.LoadTemplate(SelectedTemplateName);
                if (template != null)
                {
                    ElementList.Clear();
                    foreach (var element in template.Elements)
                    {
                        // 创建新的实例，避免引用问题
                        var newElement = new ElementComposition
                        {
                            Name = element.Name,
                            ActualValue = element.ActualValue,
                            TechnicalRequirement = element.TechnicalRequirement,
                            InternalRequirement = element.InternalRequirement,
                            Status = element.Status
                        };
                        ElementList.Add(newElement);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载模板数据失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void ExecuteRefreshTemplates()
        {
            LoadTemplateNames();
        }

        private void ExecuteOpenTemplate()
        {
            try
            {
                var dialog = new TemplateManagementDialog();
                dialog.Owner = Application.Current.MainWindow;
                
                if (dialog.ShowDialog() == true)
                {
                    // 刷新模板列表
                    LoadTemplateNames();
                    
                    // 如果当前选中的模板被删除了，选择第一个模板
                    if (!string.IsNullOrEmpty(SelectedTemplateName) && !TemplateNames.Contains(SelectedTemplateName))
                    {
                        SelectFirstTemplate();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开模板管理失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void SelectFirstTemplate()
        {
            if (TemplateNames.Count > 0)
            {
                SelectedTemplateName = TemplateNames[0];
                LoadTemplateData();
            }
        }

        private void ExecuteImportExcel()
        {
            var openFileDialog = new OpenFileDialog
            {
                Filter = "Excel文件|*.xlsx;*.xls",
                Title = "选择Excel文件"
            };

            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

                    using (var package = new ExcelPackage(new FileInfo(openFileDialog.FileName)))
                    {
                        var worksheet = package.Workbook.Worksheets[0];
                        var endRow = worksheet.Dimension.End.Row;
                        var endCol = worksheet.Dimension.End.Column;

                        // 读取元素名称和列索引
                        var elementColumnMap = new Dictionary<string, int>();
                        for (int col = 4; col <= endCol; col++)
                        {
                            string header = worksheet.Cells[2, col].Text?.Trim();
                            if (!string.IsNullOrEmpty(header))
                            {
                                if (header.EndsWith("%"))
                                {
                                    header = header.TrimEnd('%');
                                }
                                elementColumnMap[header] = col;
                            }
                        }

                        if (elementColumnMap.Count == 0)
                        {
                            MessageBox.Show("未能在Excel文件中找到任何化学元素列头。请确保第二行从第四列开始包含元素名称（如'Al%', 'Si'等）。", "导入警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                            return;
                        }

                        // 保存当前模板数据
                        var currentTemplates = ElementList.ToList();
                        ElementList.Clear();

                        // 遍历数据行
                        int addedElementsCount = 0;
                        for (int row = 3; row <= endRow; row++)
                        {
                            foreach (var entry in elementColumnMap)
                            {
                                string elementName = entry.Key;
                                int columnIndex = entry.Value;

                                string actualValueText = worksheet.Cells[row, columnIndex].Text?.Trim();

                                if (double.TryParse(actualValueText, out double actualValue))
                                {
                                    var element = new ElementComposition
                                    {
                                        Name = elementName,
                                        ActualValue = actualValue,
                                    };

                                    // 从保存的模板中查找对应的要求
                                    var template = currentTemplates.FirstOrDefault(e => e.Name == element.Name);
                                    if (template != null)
                                    {
                                        element.TechnicalRequirement = template.TechnicalRequirement;
                                        element.InternalRequirement = template.InternalRequirement;
                                        element.Status = CheckStatus(element);
                                    }
                                    else
                                    {
                                        element.TechnicalRequirement = "";
                                        element.InternalRequirement = "";
                                        element.Status = "未知";
                                    }

                                    ElementList.Add(element);
                                    addedElementsCount++;
                                }
                            }
                        }
                        
                        if (addedElementsCount == 0)
                        {
                            MessageBox.Show("未能从Excel文件中导入任何有效数据。请检查Excel文件内容和格式，确保数据从第三行开始且数值可解析。", "导入警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                        }
                        else
                        {
                            MessageBox.Show($"成功导入 {addedElementsCount} 条元素数据。", "导入成功", MessageBoxButton.OK, MessageBoxImage.Information);
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"导入Excel失败：{ex.Message}\n请确保Excel文件没有被其他程序占用，并且格式正确。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void ExecuteOpenMaterial()
        {
            try
            {
                var dialog = new MaterialManagementDialog();
                dialog.Owner = Application.Current.MainWindow;
                dialog.ShowDialog();
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开材料管理失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private (double min, double max) ParseRange(string range)
        {
            if (string.IsNullOrEmpty(range)) return (0, 0);

            range = range.Replace(" ", "");

            if (range.Contains("~"))
            {
                var parts = range.Split('~', StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length == 2)
                {
                    if (TryParseValue(parts[0], out double min) && TryParseValue(parts[1], out double max))
                    {
                        if (min > max)
                        {
                            (min, max) = (max, min);
                        }
                        return (min, max);
                    }
                }
            }
            else if (range.Contains("≤"))
            {
                if (TryParseValue(range.Replace("≤", ""), out double value))
                {
                    return (double.MinValue, value);
                }
            }
            else if (range.Contains("≥"))
            {
                if (TryParseValue(range.Replace("≥", ""), out double value))
                {
                    return (value, double.MaxValue);
                }
            }
            else if (range.Contains("＜"))
            {
                if (TryParseValue(range.Replace("＜", ""), out double value))
                {
                    return (double.MinValue, value);
                }
            }
            else if (range.Contains("＞"))
            {
                if (TryParseValue(range.Replace("＞", ""), out double value))
                {
                    return (value, double.MaxValue);
                }
            }
            else
            {
                if (TryParseValue(range, out double value))
                {
                    return (value, value);
                }
            }

            return (0, 0);
        }

        private bool TryParseValue(string value, out double result)
        {
            value = value.Replace("≤", "").Replace("≥", "").Replace("＜", "").Replace("＞", "");
            return double.TryParse(value, out result);
        }

        private bool IsInRange(double value, (double min, double max) range)
        {
            return value >= range.min && value <= range.max;
        }

        private string CheckStatus(ElementComposition element)
        {
            if (string.IsNullOrEmpty(element.TechnicalRequirement) || 
                string.IsNullOrEmpty(element.InternalRequirement))
            {
                return "未知";
            }

            try
            {
                var technicalRange = ParseRange(element.TechnicalRequirement);
                var internalRange = ParseRange(element.InternalRequirement);

                if (IsInRange(element.ActualValue, internalRange))
                {
                    return "合格";
                }
                else if (IsInRange(element.ActualValue, technicalRange))
                {
                    return "内控异常";
                }
                else
                {
                    return "不合格";
                }
            }
            catch
            {
                return "未知";
            }
        }

        private void ExecuteAutoAdjust()
        {
            try
            {
                // 筛选出不在内控范围内的元素
                var outOfRangeElements = ElementList.Where(e => e.Status != "合格").ToList();
                
                if (outOfRangeElements.Count == 0)
                {
                    MessageBox.Show("所有元素都在内控范围内，无需调整。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                // 获取所有可用材料
                var materialNames = _materialService.GetAllMaterialNames();
                if (materialNames.Count == 0)
                {
                    MessageBox.Show("没有可用的材料，请先添加材料。", "提示", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                // 创建材料选择对话框
                var materialSelectionDialog = new MaterialSelectionDialog(materialNames, outOfRangeElements);
                materialSelectionDialog.Owner = Application.Current.MainWindow;
                
                if (materialSelectionDialog.ShowDialog() == true)
                {
                    var selectedMaterials = materialSelectionDialog.SelectedMaterials;
                    var targetValues = materialSelectionDialog.TargetValues;
                    
                    // 计算需要添加的材料重量
                    var adjustmentResult = CalculateMaterialAdjustment(outOfRangeElements, selectedMaterials, targetValues);
                    
                    // 显示调整结果
                    ShowAdjustmentResult(adjustmentResult);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"自动调整失败：{ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private class AdjustmentResult
        {
            public string MaterialName { get; set; } = "";
            public double RequiredWeight { get; set; }
            public Dictionary<string, double> ElementContributions { get; set; } = new Dictionary<string, double>();
        }

        private List<AdjustmentResult> CalculateMaterialAdjustment(
            List<ElementComposition> outOfRangeElements, 
            Dictionary<string, bool> selectedMaterials, 
            Dictionary<string, double> targetValues)
        {
            var results = new List<AdjustmentResult>();
            
            foreach (var materialName in selectedMaterials.Where(kvp => kvp.Value).Select(kvp => kvp.Key))
            {
                var material = _materialService.LoadMaterial(materialName);
                if (material == null) continue;

                var result = new AdjustmentResult { MaterialName = materialName };
                var maxRequiredWeight = 0.0;

                // 计算每种元素需要的材料重量
                foreach (var element in outOfRangeElements)
                {
                    if (targetValues.ContainsKey(element.Name))
                    {
                        var targetValue = targetValues[element.Name];
                        var currentValue = element.ActualValue;
                        var requiredIncrease = targetValue - currentValue;

                        if (requiredIncrease > 0)
                        {
                            // 查找材料中该元素的含量
                            var materialElement = material.Elements.FirstOrDefault(e => e.ElementName == element.Name);
                            if (materialElement != null && materialElement.Value > 0)
                            {
                                // 计算需要的材料重量 = 需要的元素增加量 / 材料中该元素的含量
                                var requiredWeight = requiredIncrease / (materialElement.Value / 100.0); // 假设含量是百分比
                                maxRequiredWeight = Math.Max(maxRequiredWeight, requiredWeight);
                                
                                result.ElementContributions[element.Name] = requiredIncrease;
                            }
                        }
                    }
                }

                result.RequiredWeight = maxRequiredWeight;
                if (result.RequiredWeight > 0)
                {
                    results.Add(result);
                }
            }

            return results;
        }

        private void ShowAdjustmentResult(List<AdjustmentResult> results)
        {
            if (results.Count == 0)
            {
                MessageBox.Show("无法计算出有效的调整方案。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            var message = "自动调整计算结果：\n\n";
            foreach (var result in results)
            {
                message += $"材料：{result.MaterialName}\n";
                message += $"建议添加重量：{result.RequiredWeight:F2} kg\n";
                message += "元素贡献：\n";
                foreach (var contribution in result.ElementContributions)
                {
                    message += $"  {contribution.Key}: +{contribution.Value:F3}%\n";
                }
                message += "\n";
            }

            MessageBox.Show(message, "调整结果", MessageBoxButton.OK, MessageBoxImage.Information);
        }
    }
} 